import dict from '../core/dict';
import utils from '../core/utils';
import logger from '../core/logger';
import current from '../core/current';
import userClient from '../apis/userClient';
import globalData from '../core/globalData';
import mangaClient from '../apis/mangaClient';
import common from '@ohos.app.ability.common';
import relationalStore from '@ohos.data.relationalStore';
import mangaDataItem from '../models/logic/mangaDataItem';

export default class serviceCache {
  private context: common.Context;
  private static _instance: serviceCache;

  private constructor(context: common.Context) {
    this.context = context;
    this.init();
  }

  public static get instance(): serviceCache {
    return this._instance;
  }

  public static createInstance(context: common.Context): serviceCache {
    if (this._instance == null)
      this._instance = new serviceCache(context);
    return this._instance;
  }

  private get rdbStore() {
    return globalData.cardRdbStore;
  }

  private async init() {
    try {
      if (utils.isEmpty(this.rdbStore)) {
        await relationalStore.getRdbStore(this.context, {
          name: 'CardDatabase.db',
          securityLevel: relationalStore.SecurityLevel.S1,
          encrypt: false
        }).then((rdbStore: relationalStore.RdbStore) => {
          if (!utils.isEmpty(rdbStore)) {
            rdbStore.executeSql(dict.CARD_TABLE_FORM)
            globalData.cardRdbStore = rdbStore;
          }
        });
      }
    } catch (e) {
      logger.error(e);
    }
  }

  private clear() {
    try {
      let predicates: relationalStore.RdbPredicates = new relationalStore.RdbPredicates(dict.CARD_TABLE_NAME);
      this.rdbStore.delete(predicates);
    } catch (e) {
      logger.error(e);
    }
  }

  public loadData() {
    try {
      if (!current.instance.login) {
        mangaClient.getRecommend(1).then((res) => {
          if (typeof res != 'string') {
            this.clear();
            for (let item of res.list) {
              let desc = (item.authors as Array<any>).join('/');
              this.add(item.title, item.vertical_cover, desc, item.comic_id.toString());
            }
          }
        });
      } else {
        userClient.followList(2, 1).then((res) => {
          if (typeof res != 'string') {
            this.clear();
            for (let item of res)
              this.add(item.title, item.vcover, '', item.comic_id.toString());
          }
        });
      }
    } catch (e) {
      logger.error(e);
    }
  }

  private add(title: string, cover: string, desc: string, id: string) {
    try {
      let obj = {
        'comicId': id,
        'comicName': title,
        'cover': cover,
        'desc': desc
      };
      this.rdbStore.insert(dict.CARD_TABLE_NAME, obj);
    } catch (e) {
      logger.error(e);
    }
  }

  public getListData(): Promise<mangaDataItem[]> {
    return new Promise((resolve) => {
      let array = [];
      try {
        let predicates: relationalStore.RdbPredicates = new relationalStore.RdbPredicates(dict.CARD_TABLE_NAME);
        this.rdbStore.query(predicates).then((resultSet: relationalStore.ResultSet) => {
          if (resultSet.rowCount > 0) {
            resultSet.goToFirstRow();
            do {
              let comicId: string = resultSet.getString(resultSet.getColumnIndex('comicId'));
              let comicName: string = resultSet.getString(resultSet.getColumnIndex('comicName'));
              let cover: string = resultSet.getString(resultSet.getColumnIndex('cover'));
              let desc: string = resultSet.getString(resultSet.getColumnIndex('desc'));
              array.push(new mangaDataItem(comicName, cover, desc, comicId));
            } while (resultSet.goToNextRow());
            resultSet.close();
          }
          resolve(array);
        }).catch((res) => {
          logger.error(res);
          resolve(array);
        });
      } catch (e) {
        logger.error(e);
        resolve(array);
      }
    });
  }

  private toFormData(dataSource: mangaDataItem[]): Promise<object> {
    return new Promise((resolve) => {
      let formData = {};
      try {
        let length = dataSource.length;
        let start = utils.getRandomInt(length);
        if (start >= length) start = 0;
        let item = dataSource[start];
        let end = start + 1;
        if (end >= length) end = 0;
        let last = dataSource[end];
        utils.buildMemoryImage(this.context, [item.cover, last.cover]).then((res) => {
          let fileInfo = {};
          let imageName = res[0].fileName, lastImageName = res[1].fileName;
          fileInfo[imageName] = res[0].fileId;
          fileInfo[lastImageName] = res[1].fileId;
          formData = {
            'formImages': fileInfo,
            'comicId': item.comicId,
            'mangaTitle': item.title,
            'mangaDescribe': item.desc,
            'lastComicId': last.comicId,
            'lastMangaTitle': last.title,
            'lastMangaDescribe': last.desc,
            'mangaImage': `memory://${imageName}`,
            'lastMangaImage': `memory://${lastImageName}`
          };
          resolve(formData);
        });
      } catch (e) {
        logger.error(e);
        resolve(formData);
      }
    });
  }

  public async getFormData(dataSource: mangaDataItem[]): Promise<object> {
    return new Promise((resolve) => {
      this.toFormData(dataSource).then((res) => {
        resolve(res);
      });
    });
  }
}